﻿Imports System
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Globalization

''' <summary>
''' bla bla bla 
''' </summary>
<ComVisible(False)> _
Public Class dmnCalender

    Enum enmZoomMode
        'Year
        'Month
        Week
        Hour_6
        Hour_4
        Hour
        HalfHour
        Min_15
    End Enum
#Region "****************************************************************************** Constructor"
    Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        comZoom.Items.Clear()

        For Each zoom As dmnCalender.enmZoomMode In [Enum].GetValues(GetType(dmnCalender.enmZoomMode))
            comZoom.Items.Add(zoom)
        Next
        comZoom.SelectedItem = enmZoomMode.Hour
        DateTimePicker1.Value = Date.Now
        CreateContextMenu()

        Show()
    End Sub
#End Region

#Region "****************************************************************************** Private "
    Private _Zoom As enmZoomMode = enmZoomMode.Hour
    Private _WorkDayStart As Date = DateAndTime.DateValue("7:00")
    Private _WorkDayEnd As Date = DateAndTime.DateValue("17:30")
    Private _dvEvents As DataView
    Private _dvDayProperties As DataView
    Private _SystemID As Int32 = -1
    Private TimeValue As Int32 = 60
    Private WithEvents lmnuContextMenu As New ContextMenu
    Private _ActiveColour As Color = Color.WhiteSmoke
    Private _InActiveColour As Color = Color.LightGray
    Private ActiveColour As Color = Color.WhiteSmoke
    Private InActiveColour As Color = Color.LightGray
    Private lStartOfDayPos As Integer = 0
    Private icon_Holiday As String = "Holiday"
    Private icon_Default As String = "Default"
    Private icon_Other As String = "Other"
    Private _MouseButtonState As Boolean = False

    Private Sub CreateContextMenu()

        lmnuContextMenu.MenuItems.Add("Add New Item", New System.EventHandler(AddressOf AddNewItemToTimeSlot))        
        lmnuContextMenu.MenuItems.Add("Time slot Non Working", New System.EventHandler(AddressOf TimeSlotPropertiesNonWorking))
        lmnuContextMenu.MenuItems.Add("Time slot Working", New System.EventHandler(AddressOf TimeSlotPropertiesWorking))

    End Sub

    Private Sub TimeSlotPropertiesNonWorking(ByVal sender As Object, ByVal e As System.EventArgs)       
        Dim lpnl As TimeSlot = CType(lmnuContextMenu.Tag, TimeSlot)

        If _dvDayProperties IsNot Nothing Then
            _dvDayProperties.RowFilter = "StartDateTime = " & lpnl.StartTime.ToOADate
            If _dvDayProperties.Count <= 0 Then
                _dvDayProperties.Table.Rows.Add()
                Dim dt As DataTable = _dvDayProperties.Table
                Dim dr As DataRow = dt.NewRow
                dr("StartDateTime") = lpnl.StartTime.ToOADate
                dr("EndDateTime") = lpnl.EndTime.ToOADate
                dr("FullDay") = 0
                dt.Rows.Add(dr)
            End If
            lpnl.Icon = ImageList1.Images(icon_Holiday)
        End If

    End Sub

    Private Sub TimeSlotPropertiesWorking(ByVal sender As Object, ByVal e As System.EventArgs)        
        Dim lpnl As TimeSlot = CType(lmnuContextMenu.Tag, TimeSlot)
        If _dvDayProperties IsNot Nothing Then            
            lpnl.Icon = ImageList1.Images(icon_Default)
        End If
    End Sub

    Private Function GetBGColour(ByRef pnl As TimeSlot, ByRef pDate As Date) As Color
        Dim Filter As String = String.Empty
        Dim retColour As Color = _ActiveColour

        If pnl.StartTime.ToOADate < _WorkDayStart.ToOADate Then
            retColour = _InActiveColour
        ElseIf pnl.StartTime.ToOADate > _WorkDayEnd.ToOADate Then
            retColour = InActiveColour            
        Else
            retColour = ActiveColour
            If lStartOfDayPos = 0 Then lStartOfDayPos = pnl.Top
        End If

        If _dvDayProperties IsNot Nothing Then

            Filter = String.Format("(StartDateTime >= {0} AND EndDateTime <= {1} ) ", _
                                           pnl.StartTime.ToOADate, _
                                           pnl.EndTime.ToOADate)

            Filter &= String.Format("OR (StartDateTime <= {0} AND EndDateTime >= {1} ) ", _
                                   pnl.EndTime.ToOADate, _
                                   pnl.StartTime.ToOADate)

            _dvDayProperties.RowFilter = Filter

            If _dvDayProperties.Count > 0 Then
                pnl.Icon = ImageList1.Images(icon_Holiday)
            Else
                pnl.Icon = ImageList1.Images(icon_Default)
            End If
            _dvDayProperties.RowFilter = ""
        End If

        Return retColour
    End Function

    Private Sub LoadDataGrid()

        Dim oDataSetHelper As New DataSetHelper

        Dim filter As String
        Dim splitValue As Int32 = 0
        Dim lDays As Integer = 1
        Dim tmeTime As Date = Date.MinValue
        Dim lBackColor As Color = Color.Wheat

        splitValue = 24
        If _Zoom = enmZoomMode.Hour Then
            splitValue = 24
            TimeValue = 60
        ElseIf _Zoom = enmZoomMode.HalfHour Then
            splitValue = 48
            TimeValue = 30
        ElseIf _Zoom = enmZoomMode.Min_15 Then
            splitValue = 96
            TimeValue = 15
        ElseIf _Zoom = enmZoomMode.Hour_4 Then
            splitValue = 6
            TimeValue = 240
        ElseIf _Zoom = enmZoomMode.Hour_6 Then
            splitValue = 4
            TimeValue = 360
        ElseIf _Zoom = enmZoomMode.Week Then
            splitValue = 24
            TimeValue = 60
            lDays = 7
        Else
            splitValue = 1
            TimeValue = 1440
        End If
        pnlDetail1.Enabled = False
        pnlDetail1.Visible = False

        Application.DoEvents()
        pnlDetail1.HorizontalScroll.Value = 0
        pnlDetail1.VerticalScroll.Value = 0
        pnlMain.Controls.Clear()
        pnlHeader.Controls.Clear()
        pnlMain.Left = 0
        pnlMain.Top = 0
        pnlMain.Width = pnlDetail1.Width

        pnlMain.Height = 2000
        lStartOfDayPos = 0
        For iDays As Integer = 1 To lDays
            Dim DayTag As String = iDays
            Dim pnlDay As New Panel
            Dim lblDayLabel As New Label
            Dim lDate As Date = DateAdd(DateInterval.Day, iDays - 1, DateTimePicker1.Value.Date)

            pnlDay.Controls.Clear()
            pnlDay.Parent = pnlMain
            pnlDay.Width = (pnlDay.Parent.Width * 1.5) / (lDays + 1)
            pnlDay.Top = 0
            pnlDay.Left = (iDays - 1) * pnlDay.Width
            pnlDay.Height = pnlDay.Parent.Height

            lblDayLabel.Parent = pnlHeader
            lblDayLabel.Left = pnlDay.Left
            lblDayLabel.Width = pnlDay.Width
            lblDayLabel.Text = Format(lDate, "ddd dd")
            lblDayLabel.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
            lblDayLabel.TextAlign = ContentAlignment.MiddleCenter

            Dim pnlDayDetail As New Panel
            ' Day ***********************************************************        
            pnlDayDetail.Controls.Clear()
            pnlDayDetail.Parent = pnlDay
            pnlDayDetail.Left = 0
            pnlDayDetail.Top = 0
            pnlDayDetail.Height = 20
            pnlDayDetail.Height = 20 * (splitValue + 2)
            pnlDayDetail.Width = pnlDayDetail.Parent.Width
            pnlDayDetail.Tag = DayTag

            pnlDayDetail.BorderStyle = BorderStyle.FixedSingle
            pnlDayDetail.HorizontalScroll.Enabled = False
            pnlDayDetail.VerticalScroll.Enabled = False
            Application.DoEvents()
            tmeTime = Date.MinValue
            _WorkDayStart = FormatDateTime(lDate.ToString, DateFormat.ShortDate) & " 07:00 AM"
            _WorkDayEnd = FormatDateTime(lDate.ToString, DateFormat.ShortDate) & " 17:00 PM"

            For iTimeSlot As Int32 = 1 To splitValue
                Dim timeSlot1 As New TimeSlot
                timeSlot1.Parent = pnlDayDetail
                timeSlot1.Height = 20
                timeSlot1.Width = 300
                timeSlot1.Left = 0
                timeSlot1.Top = (iTimeSlot - 1) * timeSlot1.Height
                timeSlot1.StartTime = FormatDateTime(lDate.ToString, DateFormat.ShortDate) & " " & FormatDateTime(tmeTime, DateFormat.LongTime)
                timeSlot1.EndTime = DateAdd(DateInterval.Minute, TimeValue - 1, timeSlot1.StartTime)
                timeSlot1.Icon = ImageList1.Images(icon_Default)
                timeSlot1.SlotTime = tmeTime

                timeSlot1.ContextMenu = lmnuContextMenu

                AddHandler timeSlot1.MouseDown, AddressOf MyMouseDown
                AddHandler timeSlot1.MouseUp, AddressOf MyMouseUp
                AddHandler timeSlot1.MouseMove, AddressOf MyMove

                timeSlot1.BackColor = GetBGColour(timeSlot1, lDate)

                If _dvEvents IsNot Nothing Then

                    filter = String.Format("(StartDateTime >= {0} AND EndDateTime <= {1} ) ", _
                                           timeSlot1.StartTime.ToOADate, _
                                           timeSlot1.EndTime.ToOADate)

                    filter &= String.Format("OR (StartDateTime <= {0} AND EndDateTime >= {1} ) ", _
                                           timeSlot1.EndTime.ToOADate, _
                                           timeSlot1.StartTime.ToOADate)

                    _dvEvents.RowFilter = "SystemID = " & _SystemID.ToString & " AND " & filter
                    If _dvEvents.Count > 0 Then
                        AddNewItemToTimeSlot(timeSlot1, Nothing)
                    End If
                End If

                tmeTime = DateAdd(DateInterval.Minute, TimeValue, tmeTime)
            Next
        Next
        pnlDetail1.Enabled = True
        pnlDetail1.Visible = True
        pnlDetail1.VerticalScroll.Minimum = 0
        pnlDetail1.VerticalScroll.Maximum = pnlMain.Height
        pnlDetail1.VerticalScroll.Value = lStartOfDayPos
        pnlMain.Top = lStartOfDayPos * -1

    End Sub

    Private Sub AddNewItemToTimeSlot(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim lpnl As TimeSlot
        If TypeOf sender Is MenuItem Then
            lpnl = CType(lmnuContextMenu.Tag, TimeSlot)
        Else
            lpnl = sender
        End If

        If _SystemID = -1 Then Exit Sub
        lpnl.AddItem = CType(lpnl.StartTime, Date).ToString

        If e IsNot Nothing Then
            _dvEvents.Table.Rows.Add()
            Dim dt As DataTable = _dvEvents.Table
            Dim dr As DataRow = dt.NewRow

            dr("SystemID") = _SystemID
            dr("StartDateTime") = lpnl.StartTime.ToOADate
            dr("EndDateTime") = lpnl.EndTime.ToOADate
            dr("Name") = lpnl.StartTime.ToString

            dt.Rows.Add(dr)
        End If
    End Sub

    Private Sub MyMouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim lPnl As TimeSlot = CType(sender, TimeSlot)
        _MouseButtonState = True
        lPnl.Selected = _MouseButtonState
        Application.DoEvents()
        Debug.Print(Date.Now.ToString & " " & _MouseButtonState & " MyMouseDown")
    End Sub

    Private Sub MyMove(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim lPnl As TimeSlot = CType(sender, TimeSlot)
        lPnl.Selected = _MouseButtonState
        Application.DoEvents()
        Debug.Print(Date.Now.ToString & " " & _MouseButtonState & " MyMove " & lPnl.StartTime)
    End Sub

    Private Sub MyMousePosition(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim lPnl As TimeSlot = CType(sender, TimeSlot)
        lPnl.Selected = _MouseButtonState
        Application.DoEvents()
        Debug.Print(Date.Now.ToString & " " & _MouseButtonState & " MyMove " & lPnl.StartTime)
    End Sub

    Private Sub MyMouseEnter(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim lPnl As TimeSlot = CType(sender, TimeSlot)
        lPnl.Selected = _MouseButtonState
        Application.DoEvents()
        Debug.Print(Date.Now.ToString & " " & _MouseButtonState)
    End Sub

    Private Sub MyMouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        _MouseButtonState = False
        Application.DoEvents()
    End Sub

    Private Sub MyMouseHover(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim lPnl As TimeSlot = CType(sender, TimeSlot)
        lPnl.Selected = _MouseButtonState
        Application.DoEvents()
        Debug.Print(Date.Now.ToString & " " & _MouseButtonState & " MyMouseHover")
    End Sub

    Private Sub MyDragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
        Dim lPnl As TimeSlot = CType(sender, TimeSlot)
        lPnl.Selected = _MouseButtonState
        Application.DoEvents()
        Debug.Print(Date.Now.ToString & " " & _MouseButtonState)
    End Sub
    Private Sub UpdateTimeSlot(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim lPnl As TimeSlot = CType(sender, TimeSlot)
        lPnl.Selected = True

        'CType(sender, TimeSlot).ContextMenu = lmnuContextMenu
        'lmnuContextMenu.Tag = sender        
    End Sub

    Private Sub comZoom_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comZoom.SelectedIndexChanged
        Zoom = comZoom.SelectedItem
        Show()
    End Sub

    Private Sub DateTimePicker1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged
        Zoom = comZoom.SelectedItem
        Show()
    End Sub

#End Region

#Region "****************************************************************************** Properties"

    <Browsable(False)> _
    <DefaultValue(-1)> _
    Public Property SystemID() As Int32
        Get
            Return _SystemID
        End Get
        Set(ByVal value As Int32)
            _SystemID = value
        End Set
    End Property

    <Browsable(False)> _
    Public Property dvEvents() As DataView
        Get
            Return _dvEvents
        End Get
        Set(ByVal value As DataView)
            _dvEvents = value
        End Set
    End Property

    <Browsable(False)> _
    Public Property dvDayProperties() As DataView
        Get
            Return _dvDayProperties
        End Get
        Set(ByVal value As DataView)
            _dvDayProperties = value
        End Set
    End Property

    <Browsable(True)> _
    <DefaultValue("7:00")> _
    <Category("Behavior")> _
    <Description("Start of work day")> _
    Public Property WorkDayStart() As Date
        Get
            Return _WorkDayStart
        End Get
        Set(ByVal value As Date)
            _WorkDayStart = value
        End Set
    End Property

    <Browsable(True)> _
    <DefaultValue("16:30")> _
    <Category("Behavior")> _
    <Description("End of work day")> _
    Public Property WorkDayEnd() As Date
        Get
            Return _WorkDayEnd
        End Get
        Set(ByVal value As Date)
            _WorkDayEnd = value
        End Set
    End Property

    <Browsable(True)> _
    <DefaultValue(enmZoomMode.Hour)> _
    <Category("Behavior")> _
    <Description("Zoom level")> _
    Public Property Zoom() As enmZoomMode
        Get
            Return _Zoom
        End Get
        Set(ByVal value As enmZoomMode)
            _Zoom = value
        End Set
    End Property

    Public Shadows Sub Show()
        LoadDataGrid()
    End Sub

#End Region

    Private Sub pnlMain_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles pnlMain.DragOver
        Debug.Print("Hello")
    End Sub

    Private Sub pnlMain_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pnlMain.MouseDown

    End Sub
End Class


Friend Class TimeSlot
    Inherits Panel

#Region "****************************************************************************** Private "
    Private _StartTime As Date = Date.MinValue
    Private _EndTime As Date = Date.MinValue
    Private _txt As Label
    Private _Icon As New PictureBox
    Private _Selected As Boolean = False
    Private _SelectedColour As Color = Color.Aqua
#End Region

#Region "****************************************************************************** Constructor"
    Sub New()
        Me.BorderStyle = BorderStyle.FixedSingle
        Me.Height = 20
        Me.Width = 300
        Me.Left = 0

        _Icon = New PictureBox
        _Icon.Parent = Me
        _Icon.Name = "Icon"
        _Icon.Image = Nothing
        _Icon.Height = Me.Height
        _Icon.Width = Me.Height
        _Icon.Top = 0
        _Icon.Left = 0
        _Icon.BringToFront()

        _txt = New Label
        _txt.Parent = Me
        _txt.Name = "Label"
        _txt.Left = _Icon.Width
        _txt.Top = 0
        _txt.Width = 40
        _txt.Height = _txt.Parent.Height
        _txt.TextAlign = ContentAlignment.MiddleCenter
        _txt.Text = FormatDateTime(_StartTime, DateFormat.ShortTime)
        _txt.BorderStyle = Windows.Forms.BorderStyle.FixedSingle


        'AddHandler MyBase.MouseDown, AddressOf MouseDown
    End Sub
#End Region

#Region "****************************************************************************** Public"

    Public Property AddItem() As String
        Get
            If Me.Controls("ItemButton") IsNot Nothing Then
                Return Me.Controls("ItemButton").Text
            Else
                Return String.Empty
            End If
        End Get
        Set(ByVal value As String)
            If Me.Controls("ItemButton") Is Nothing Then
                Dim btn As New Button
                btn.Name = "ItemButton"
                btn.Parent = Me
                btn.Height = Me.Height
                btn.Left = Me.Controls("Label").Left + Me.Controls("Label").Width
                btn.Top = 0
                btn.Width = 120
                btn.Text = CType(Me.StartTime, Date).ToString
                AddHandler btn.Click, AddressOf ViewEvent
            End If
        End Set
    End Property

    Public Property SlotTime() As String
        Get
            Return _txt.Text
        End Get
        Set(ByVal value As String)
            _txt.Text = FormatDateTime(value, DateFormat.ShortTime)
        End Set
    End Property

    Public Property Icon() As Image
        Get
            Return CType(Me.Controls("Icon"), PictureBox).Image
        End Get
        Set(ByVal value As Image)
            CType(Me.Controls("Icon"), PictureBox).Image = value
        End Set
    End Property

    Public Property StartTime() As Date
        Get
            Return _StartTime
        End Get
        Set(ByVal value As Date)
            _StartTime = value
        End Set
    End Property

    Public Property EndTime() As Date
        Get
            Return _EndTime
        End Get
        Set(ByVal value As Date)
            _EndTime = value
        End Set
    End Property

    Public Property Selected() As Boolean
        Get
            Return _Selected
        End Get
        Set(ByVal value As Boolean)
            _Selected = value
            If _Selected Then
                Me.BackColor = _SelectedColour
            Else
                Me.BackColor = Color.White
            End If
        End Set
    End Property
    Private Sub ViewEvent(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim oFrm As New frmDetail
        oFrm.TextBox1.Text = CType(sender, Button).Text
        oFrm.ShowDialog()
    End Sub

    Protected Shadows Sub MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        'MyBase.BackColor = Color.LightSkyBlue
    End Sub

#End Region

End Class